home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Light ROM 1
/
LIGHT-ROM 1 (Amiga Library Services)(1994).iso
/
ffdisks
/
d935.lha
/
AmiCDROM
/
devsupp.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-12-20
|
14KB
|
499 lines
/* devsupp.c:
*
* Support routines for the device handler.
* - debugging
* - Mountlist "Startup" field parsing
*
* ----------------------------------------------------------------------
* This code is (C) Copyright 1993 by Frank Munkert.
* All rights reserved.
* This software may be freely distributed and redistributed for
* non-commercial purposes, provided this notice is included.
* ----------------------------------------------------------------------
* History:
*
* 21-Nov-93 fmu New option SCANINTERVAL.
* 14-Nov-93 fmu Added Handle_Control_Packet for 'cdcontrol' program.
* 10-Nov-93 fmu New options SHOWVERSION and HFSFIRST.
* 23-Oct-93 fmu MacHFS options added.
* 15-Oct-93 fmu Adapted to new VOLUME structure.
*/
/*
* Extract information from Mountlist "Startup" field.
*/
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#ifdef _DCC
#define abs
#endif
#include <exec/types.h>
#include <clib/dos_protos.h>
#include "cdrom.h"
#include "device.h"
#include "devsupp.h"
#include "intui.h"
#include "generic.h"
#include "params.h"
#include "cdcontrol.h"
#ifdef AZTEC_C
#include <pragmas/dos_lib.h>
#endif
#ifdef LATTICE
#include <pragmas/dos_pragmas.h>
extern struct DosLibrary *DOSBase;
#endif
#if defined(_DCC) && defined(REGISTERED)
#include <pragmas/dos_pragmas.h>
extern struct Library *DOSBase;
#endif
static char *TheVersion = "$VER: CDROM-Handler " VERSION;
int
Get_Startup (LONG p_startup)
{
enum {
ARG_DEVICE,
ARG_UNIT,
ARG_FAST,
ARG_LOWERCASE,
ARG_ROCKRIDGE,
ARG_TRACKDISK,
ARG_MACTOISO,
ARG_CONVERTSPACES,
ARG_SHOWVERSION,
ARG_HFSFIRST,
ARG_STDBUFFERS,
ARG_FILEBUFFERS,
ARG_DATAEXT,
ARG_RESOURCEEXT,
ARG_SCANINTERVAL,
ARG_PLAYCDDA,
ARGCOUNT
};
STRPTR Args[ARGCOUNT],Index;
UBYTE LocalBuffer[100];
struct RDArgs *ArgsPtr;
int result = FALSE,len,i;
/* Clear the argument vector. */
memset (Args, 0, sizeof(Args));
/* valid startup entry? */
if (!p_startup) {
Display_Error ("Filesystem startup entry invalid");
return FALSE;
}
/* Get the contents of the startup field. */
len = ((STRPTR)(BADDR(p_startup)))[0];
if (len > sizeof (LocalBuffer) - 1)
len = sizeof (LocalBuffer) - 1;
memcpy (LocalBuffer, ((STRPTR)(BADDR(p_startup))) + 1, len);
/* Provide null-termination. */
LocalBuffer[len] = 0;
/* Remove leading quotes. */
for (i = 0 ; i < len ; i++) {
if (LocalBuffer[i] != ' ') {
if (LocalBuffer[i] == '\"')
LocalBuffer[i] = ' ';
break;
}
}
/* Remove trailing quotes. */
for (i = len - 1 ; i >= 0 ; i--) {
if (LocalBuffer[i] != ' '){
if (LocalBuffer[i] == '\"')
LocalBuffer[i] = ' ';
break;
}
}
/* Replace "-" by spaces, except "--" which is replaced by "-". */
Index = LocalBuffer;
for (i = 0 ; i < len ; i++) {
if (LocalBuffer[i] == '-') {
if (i+1 < len && LocalBuffer[i+1] == '-') {
*Index++ = '-';
i++;
} else
*Index++ = ' ';
} else
*Index++ = LocalBuffer[i];
}
/* Provide null-termination. */
*Index = 0;
/* Don't forget the newline, or ReadArgs won't work. */
strcat ((char *) LocalBuffer, "\n");
if (ArgsPtr = (struct RDArgs *) AllocDosObjectTags (DOS_RDARGS,TAG_DONE)) {
/* Don't prompt for input! */
ArgsPtr -> RDA_Flags |= RDAF_NOPROMPT;
/* Set up for local parsing. */
ArgsPtr->RDA_Source.CS_Buffer = LocalBuffer;
ArgsPtr->RDA_Source.CS_Length = strlen ((char *) LocalBuffer);
ArgsPtr->RDA_Source.CS_CurChr = 0;
/* Read the arguments. */
if (ReadArgs ((UBYTE *)
"D=DEVICE,U=UNIT/N,F=FAST/S,L=LOWERCASE/S,"
"R=ROCKRIDGE/S,T=TRACKDISK/S,"
"MI=MACTOISO/S,CS=CONVERTSPACES/S,"
"SV=SHOWVERSION/S,HF=HFSFIRST/S,"
"SB=STDBUFFERS/K/N,FB=FILEBUFFERS/K/N,"
"DE=DATAEXT/K,RE=RESOURCEEXT/K,"
"SI=SCANINTERVAL/K/N,PC=PLAYCDDA/K",
(LONG *) Args, ArgsPtr)) {
result = TRUE;
if (Args[ARG_DEVICE]) {
len = strlen((char *) (Args[ARG_DEVICE]));
if (len >= sizeof (g_device)) {
Display_Error ("Device name entry too long");
result = FALSE;
} else
strcpy (g_device, (char *) (Args[ARG_DEVICE]));
} else
Display_Error("Device name entry missing");
g_unit = *(long *) (Args[ARG_UNIT]);
g_fastmem = (Args[ARG_FAST] != NULL);
g_map_to_lowercase = (Args[ARG_LOWERCASE] != NULL);
g_use_rock_ridge = (Args[ARG_ROCKRIDGE] != NULL);
g_trackdisk = (Args[ARG_TRACKDISK] != NULL);
g_show_version_numbers = (Args[ARG_SHOWVERSION] != NULL);
g_hfs_first = (Args[ARG_HFSFIRST] != NULL);
if (Args[ARG_STDBUFFERS]) {
g_std_buffers = *(long *) (Args[ARG_STDBUFFERS]);
if (g_std_buffers <= 0) {
Display_Error ("Illegal number of standard buffers: %ld", g_std_buffers);
result = FALSE;
}
} else
g_std_buffers = 5;
if (Args[ARG_FILEBUFFERS]) {
g_file_buffers = *(long *) (Args[ARG_FILEBUFFERS]);
if (g_file_buffers <= 0) {
Display_Error ("Illegal number of file buffers: %ld", g_std_buffers);
result = FALSE;
}
} else
g_file_buffers = 5;
if (Args[ARG_DATAEXT])
strcpy (g_data_fork_extension, (char *) Args[ARG_DATAEXT]);
if (Args[ARG_RESOURCEEXT])
strcpy (g_resource_fork_extension, (char *) Args[ARG_RESOURCEEXT]);
g_convert_hfs_filenames = (Args[ARG_MACTOISO] != NULL);
g_convert_hfs_spaces = (Args[ARG_CONVERTSPACES] != NULL);
if (Args[ARG_SCANINTERVAL]) {
g_scan_interval = *(long *) (Args[ARG_SCANINTERVAL]);
if (g_scan_interval < 0)
g_scan_interval = 0;
} else
g_scan_interval = 3;
if (Args[ARG_PLAYCDDA]) {
len = strlen((char *) (Args[ARG_PLAYCDDA]));
if (len >= sizeof (g_play_cdda_command)) {
Display_Error ("PLAYCDDA command name too long");
result = FALSE;
} else
strcpy (g_play_cdda_command, (char *) (Args[ARG_PLAYCDDA]));
} else
g_play_cdda_command[0] = 0;
FreeArgs(ArgsPtr);
} else {
Fault(IoErr (), (UBYTE *) "", LocalBuffer, 100);
Display_Error ("Error while parsing \"Startup\" field in Mountlist:\n%s",
LocalBuffer + 2);
}
FreeDosObject (DOS_RDARGS, ArgsPtr);
} else
Display_Error ("Out of memory");
if (result) {
if (!(g_cd = Open_CDROM (g_device, g_unit, g_trackdisk, g_fastmem,
g_std_buffers, g_file_buffers))) {
switch (g_cdrom_errno) {
case CDROMERR_NO_MEMORY:
if (g_fastmem)
Display_Error ("Out of memory: cannot allocate buffers\n"
"(Do not use the FAST option if have no fast memory.)");
else
Display_Error ("Out of memory: cannot allocate buffers\n"
"(Try using the FAST option.)");
break;
case CDROMERR_MSGPORT:
Display_Error ("Cannot open the message port.");
break;
case CDROMERR_IOREQ:
Display_Error ("Cannot open the I/O request structure.");
break;
case CDROMERR_DEVICE:
Display_Error ("Cannot open \"%s\" unit %ld", g_device, (int) g_unit);
break;
default:
break;
}
result = FALSE;
}
}
return result;
}
int Handle_Control_Packet (ULONG p_type, ULONG p_par1, ULONG p_par2)
{
switch (p_type) {
case CDCMD_LOWERCASE:
g_map_to_lowercase = p_par1;
break;
case CDCMD_MACTOISO:
g_convert_hfs_filenames = p_par1;
break;
case CDCMD_CONVERTSPACES:
g_convert_hfs_spaces = p_par1;
break;
case CDCMD_SHOWVERSION:
g_show_version_numbers = p_par1;
break;
case CDCMD_HFSFIRST:
g_hfs_first = p_par1;
break;
case CDCMD_DATAEXT:
strcpy (g_data_fork_extension, (char *) p_par1);
break;
case CDCMD_RESOURCEEXT:
strcpy (g_resource_fork_extension, (char *) p_par1);
break;
default:
return 999;
}
return 0;
}
#if defined(NDEBUG) && defined(_DCC)
void debugmain (void)
{
}
#endif
#if !defined(NDEBUG) || defined(DEBUG_SECTORS)
char *typetostr (int ty)
{
switch(ty) {
case ACTION_DIE: return("DIE");
case ACTION_FINDUPDATE: return("OPEN-RW");
case ACTION_FINDINPUT: return("OPEN-OLD");
case ACTION_FINDOUTPUT: return("OPEN-NEW");
case ACTION_READ: return("READ");
case ACTION_WRITE: return("WRITE");
case ACTION_END: return("CLOSE");
case ACTION_SEEK: return("SEEK");
case ACTION_EXAMINE_NEXT: return("EXAMINE NEXT");
case ACTION_EXAMINE_OBJECT: return("EXAMINE OBJ");
case ACTION_INFO: return("INFO");
case ACTION_DISK_INFO: return("DISK INFO");
case ACTION_PARENT: return("PARENTDIR");
case ACTION_DELETE_OBJECT: return("DELETE");
case ACTION_CREATE_DIR: return("CREATEDIR");
case ACTION_LOCATE_OBJECT: return("LOCK");
case ACTION_COPY_DIR: return("DUPLOCK");
case ACTION_FREE_LOCK: return("FREELOCK");
case ACTION_SET_PROTECT: return("SETPROTECT");
case ACTION_SET_COMMENT: return("SETCOMMENT");
case ACTION_RENAME_OBJECT: return("RENAME");
case ACTION_INHIBIT: return("INHIBIT");
case ACTION_RENAME_DISK: return("RENAME DISK");
case ACTION_MORE_CACHE: return("MORE CACHE");
case ACTION_WAIT_CHAR: return("WAIT FOR CHAR");
case ACTION_FLUSH: return("FLUSH");
case ACTION_SCREEN_MODE: return("SCREENMODE");
case ACTION_IS_FILESYSTEM: return("IS_FILESYSTEM");
case ACTION_SAME_LOCK: return("SAME_LOCK");
case ACTION_COPY_DIR_FH: return("COPY_DIR_FH");
case ACTION_PARENT_FH: return("PARENT_FH");
case ACTION_EXAMINE_FH: return("EXAMINE_FH");
case ACTION_FH_FROM_LOCK: return("FH_FROM_LOCK");
case ACTION_CURRENT_VOLUME: return("CURRENT_VOLUME");
case ACTION_USER: return("USER");
default: return("---------UNKNOWN-------");
}
}
/*
* DEBUGGING CODE. You cannot make DOS library calls that access other
* devices from within a DOS device driver because they use the same
* message port as the driver. If you need to make such calls you must
* create a port and construct the DOS messages yourself. I do not
* do this. To get debugging info out another PROCESS is created to which
* debugging messages can be sent.
*
* You want the priority of the debug process to be larger than the
* priority of your DOS handler. This is so if your DOS handler crashes
* you have a better idea of where it died from the debugging messages
* (remember that the two processes are asyncronous from each other).
*/
extern void debugproc();
void dbinit (void)
{
TASK *task = FindTask(NULL);
Dback = CreatePort(NULL, 0);
CreateProc((UBYTE *) "DEV_DB", task->tc_Node.ln_Pri+1, (BPTR) (CTOB(debugproc)),
4096);
WaitPort(Dback); /* handshake startup */
GetMsg(Dback); /* remove dummy msg */
dbprintf("Debugger running: %s, %s\n", TheVersion+6, __TIME__);
}
void dbuninit (void)
{
MSG killmsg;
if (Dbport) {
killmsg.mn_Length = 0; /* 0 means die */
PutMsg(Dbport,&killmsg);
WaitPort(Dback); /* He's dead jim! */
GetMsg(Dback);
DeletePort(Dback);
/*
* Since the debug process is running at a greater priority, I
* am pretty sure that it is guarenteed to be completely removed
* before this task gets control again. Still, it doesn't hurt...
*/
Delay(50); /* ensure he's dead */
}
}
void dbprintf (char *format, ...)
{
va_list arg;
char buf[256];
MSG *msg;
va_start (arg, format);
if (Dbport && !DBDisable) {
vsprintf (buf, format, arg);
msg = AllocMem(sizeof(MSG)+strlen(buf)+1, MEMF_PUBLIC|MEMF_CLEAR);
msg->mn_Length = strlen(buf)+1; /* Length NEVER 0 */
strcpy((char *) (msg+1), buf);
PutMsg(Dbport,msg);
}
va_end (arg);
}
/*
* BTW, the DOS library used by debugmain() was actually openned by
* the device driver. Note: DummyMsg cannot be on debugmain()'s stack
* since debugmain() goes away on the final handshake.
*/
#ifdef LATTICE
void __saveds debugmain (void)
#else
void debugmain (void)
#endif /* LATTICE */
{
MSG *msg;
short len;
void *fh;
#ifdef LOG_MESSAGES
void *out;
#endif
Dbport = CreatePort(NULL, 0);
fh = (void *) Open ((UBYTE *) "con:0/0/640/100/debugwindow", 1006);
PutMsg(Dback, &DummyMsg);
#ifdef LOG_MESSAGES
#ifdef LOG_TO_PAR
out = (void *) Open ((UBYTE *) "PAR:", 1006);
#else
out = (void *) Open ((UBYTE *) "ram:cd.log", 1006);
#endif
#endif
for (;;) {
WaitPort(Dbport);
msg = GetMsg(Dbport);
len = msg->mn_Length;
if (len == 0)
break;
--len; /* Fix length up */
Write((BPTR) fh, msg+1, len);
#ifdef LOG_MESSAGES
Write((BPTR) out, msg+1, len);
#endif
FreeMem(msg,sizeof(MSG)+len+1);
}
Close ((BPTR) fh);
#ifdef LOG_MESSAGES
Close ((BPTR) out);
#endif
DeletePort(Dbport);
PutMsg(Dback,&DummyMsg); /* Kill handshake */
}
/*
* The assembly tag for the DOS process: CNOP causes alignment problems
* with the Aztec assembler for some reason. I assume then, that the
* alignment is unknown. Since the BCPL conversion basically zero's the
* lower two bits of the address the actual code may start anywhere around
* the label.... Sigh.... (see CreatProc() above).
*/
#ifdef AZTEC_C
#asm
public _debugproc
public _debugmain
public _geta4 ; for small memory model
cseg
nop
nop
nop
_debugproc:
nop
nop
movem.l D2-D7/A2-A6,-(sp)
jsr _geta4 ; for small memory model
jsr _debugmain
movem.l (sp)+,D2-D7/A2-A6
rts
#endasm
#endif /* AZTEC_C */
#endif /* !NDEBUG || DEBUG_SECTORS */